//
//  PhotoPickerViewController.swift
//  1-照片选择器框架
//
//  Created by yellow on 15/10/28.
//  Copyright © 2015年 yellow. All rights reserved.
//

import UIKit

/// 重用标示符
let PhotoPickerViewCellID = "PhotoPickerViewCell"


/// 设置可选的最大图片个数
let PhotoPickerViewCellMaxCount = 9


class PhotoPickerViewController: UICollectionViewController {
    
    /// 用来接收选中的图片集
    lazy var photos:[UIImage] = [UIImage]()
    
    /// 保存当前选中的S索引
    var selectedIndex = 0
    
    var isDeleteAnimator = false
    
    init(){
        let layout = PhotoPickerViewLayout()
        super.init(collectionViewLayout: layout)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //必须要在viewDidLoad中设置布局和注册cell，因为在loadView中collectionView还没有创建好
    override func viewDidLoad() {
        setUI()
    }
    
    //cell流水布局
    private class PhotoPickerViewLayout:UICollectionViewFlowLayout{
        
        //自定义布局必须要重写该方法
        private override func prepareLayout() {
            super.prepareLayout()
            
            //一排显示4个cell
            let count:CGFloat = 4
            //根据屏幕缩放比例（1x,2x,3x）设置边距
            let margin = UIScreen.mainScreen().scale * 4
            let itemWidth = ((collectionView?.bounds.width)! - (count+1)*margin) / count
            
            itemSize = CGSize(width: itemWidth, height: itemWidth)
            sectionInset = UIEdgeInsetsMake(margin, margin, 0, margin)
            minimumInteritemSpacing = margin
            minimumLineSpacing = margin
            //设置滚动方向（默认就是Vertical）为横向，cell就是竖者以Z字排列
            //scrollDirection = .Horizontal
        }
    }
}

// MARK: - 界面布局设置
extension PhotoPickerViewController{
    
    func setUI(){
        self.view.backgroundColor = UIColor.whiteColor()
        self.collectionView?.backgroundColor = UIColor(white: 0.9, alpha: 1)
        self.collectionView?.registerClass(PhotoPickerViewCell.self, forCellWithReuseIdentifier: PhotoPickerViewCellID)
    }
}


// MARK: - 数据源
extension PhotoPickerViewController{
    
    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if isDeleteAnimator && photos.count == PhotoPickerViewCellMaxCount-1 {
            isDeleteAnimator = false
            return photos.count
        }
        return photos.count + (photos.count == PhotoPickerViewCellMaxCount ? 0:1)
    }
    
    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(PhotoPickerViewCellID, forIndexPath: indexPath) as! PhotoPickerViewCell
        //设置选择cell弹出相册和移除照片选择的代理
        cell.pickerDelegate = self
        cell.image = (indexPath.item < photos.count) ? photos[indexPath.item]:nil
        
        return cell
    }
}

// MARK: - PhotoPickerViewDelegate

/// 如果协议中包含 optional 的函数，协议需要使用 @objc 修饰。因为swift中的protocol原生不支持optional（为什么呢？），必须依赖objective-C的运行时才能支持。
extension PhotoPickerViewController:PhotoPickerViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate{
    
    private func photoPickerViewCellDidAdd(cell:PhotoPickerViewCell){
        if !UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary){
            print("无权限请求相册")
        }
        
        //保存当前选中的cell的index
        selectedIndex = collectionView?.indexPathForCell(cell)?.item ?? 0
        
        let pickerVC = UIImagePickerController()
        pickerVC.delegate = self
        presentViewController(pickerVC, animated: true, completion: nil)
    }
    
    private func photoPickerViewCellDidRemove(cell:PhotoPickerViewCell){
        selectedIndex = collectionView?.indexPathForCell(cell)?.item ?? 0
        
        photos.removeAtIndex(selectedIndex)
        isDeleteAnimator = true
        
        // Animates multiple insert, delete, reload, and move operations as a group.
        collectionView?.performBatchUpdates({ () -> Void in
            
            //deletedeleteItemsAtIndexPaths，表视图的数据源需要和你插入或者删除的操作保持一致。在numberOfRowsInSection上做一个断点，确认插入或者删除记录后结果集总数要和deleteRowsAtIndexPaths操作一致
            //所以在图片到max时，进行删除时，需要返回max-1，但是我们又需要在未满图片时，显示一个可添加的cell，就可以在完成图片delete动画后再跟新数据源，从而变成原来的cell个数(需要在更新数据个数的代理中使用一个flage来表示是图片达到max后再删的)
            collectionView?.deleteItemsAtIndexPaths([NSIndexPath(forItem: selectedIndex, inSection: 0)])
            }, completion: { (_) -> Void in
               //更新数据源，切换分支
               self.collectionView?.reloadData()
        })
    }
    
    
    
    /// UIImagePickerControllerDelegate
    ///
    /// - parameter picker: 图片选择控制器
    /// - parameter info:   选择的图片对象
    @objc func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]){
        //如有需要进行等比缩放
        let selectedImage = (info[UIImagePickerControllerOriginalImage] as! UIImage).scaleToWidth(500)
        
        if selectedIndex >= photos.count {
            //追加图片
            photos.append(selectedImage)
        }else{
            //替换图片
            photos[selectedIndex] = selectedImage
        }
        // 刷新视图
        collectionView?.reloadData()

        dismissViewControllerAnimated(true, completion: nil)
    }
}



/// 自定义cell 代理
private protocol PhotoPickerViewDelegate:NSObjectProtocol{
    
    /// 点击cell，选择图片进行添加
    ///
    /// - parameter cell: 所点击的cell
    func photoPickerViewCellDidAdd(cell:PhotoPickerViewCell)
    
    /// 点击cell的移除图片按钮
    ///
    /// - parameter cell: 所点击的cell
    func photoPickerViewCellDidRemove(cell:PhotoPickerViewCell)
}

/// 自定义cell
private class PhotoPickerViewCell:UICollectionViewCell{
    
    /// 接收外部传来的参数
    var image:UIImage?{
        didSet{
            if let img = image {
                photoItem.setImage(img, forState: UIControlState.Normal)
                // 隐藏删除按钮 image == nil 就是新增按钮
                removeBtn.hidden = (image == nil)
            }else{
                //为防止重用，一定设置图片为nil的设置为添加图片
                let imagePath = NSBundle.mainBundle().bundlePath + "/PhotoPickerResource.bundle/compose_pic_add.png"
                photoItem.setImage(UIImage(contentsOfFile: imagePath), forState: UIControlState.Normal)
                removeBtn.hidden = true
            }
        }
    }
    
    //定义接收代理的类型(必须实现PhotoPickerViewDelegate协议)
    weak var pickerDelegate:PhotoPickerViewDelegate?
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setUI()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    //懒加载控件
    private lazy var photoItem:UIButton = {
        let btn = UIButton()
        let imagePath = NSBundle.mainBundle().bundlePath + "/PhotoPickerResource.bundle/compose_pic_add.png"
        btn.setImage(UIImage(contentsOfFile: imagePath), forState: UIControlState.Normal)
        btn.addTarget(self, action: "photoItemClick", forControlEvents: UIControlEvents.TouchUpInside)
        return btn
    }()
    
    @objc private func photoItemClick(){
        guard let delgate = pickerDelegate else{
            return
        }
        delgate.photoPickerViewCellDidAdd(self)
    }

    /// 移除图片按钮(右上角,默认是隐藏的,当有了照片后需要显式的设置该按钮为可见)
    private lazy var removeBtn:UIButton = {
        let btn = UIButton()
        let imagePath = NSBundle.mainBundle().bundlePath + "/PhotoPickerResource.bundle/compose_photo_close.png"
        btn.setImage(UIImage(contentsOfFile: imagePath), forState: UIControlState.Normal)
        btn.addTarget(self, action: "removeBtnClick", forControlEvents: UIControlEvents.TouchUpInside)
        btn.hidden = true
        return btn
    }()
    
    @objc private func removeBtnClick(){
        guard let delgate = pickerDelegate else{
            return
        }
        delgate.photoPickerViewCellDidRemove(self)
    }
    
    private func setUI(){
        //记住加载contentView上，否则不受控制
        contentView.addSubview(photoItem)
        contentView.addSubview(removeBtn)
        
        photoItem.imageView?.contentMode = .ScaleAspectFill
        
        //自动布局
        
        //加号背景图片按钮设置和cell大小一致
        photoItem.frame = bounds
        //移除图片按钮放在item的右上角
        removeBtn.snp_makeConstraints { (make) -> Void in
            make.top.equalTo(photoItem.snp_top)
            make.right.equalTo(photoItem.snp_right)
        }
    }
}




